﻿using Orleans.Placement;
using Orleans.Runtime.Placement;
using Orleans.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace Grain.Strategy
{
    public class SamplePlacementStrategyFixedSiloDirector : IPlacementDirector
    {
        private SiloAddress[] _silos;

        public async Task<SiloAddress> OnAddActivation(
            PlacementStrategy strategy,
            PlacementTarget target,
            IPlacementContext context)
        {
            Stopwatch sw = Stopwatch.StartNew();
            while (context.GetCompatibleSilos(target).Length < 3 && sw.Elapsed.TotalSeconds < 30) // 等待所有服务端启动
            {
                await Task.Delay(100);
            }

            if (_silos == null)
            {
                _silos = context.GetCompatibleSilos(target).OrderBy(s => s).ToArray();
                Console.WriteLine("获取所有silo");
            }
            int silo = (int)target.GrainIdentity.GetIntegerKey(out string? keyExt) % _silos.Length;
            Console.WriteLine($"silo={silo}");

            return _silos[silo];
        }
    }

    [Serializable]
    public sealed class SamplePlacementStrategy : PlacementStrategy
    {
    }

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public sealed class SamplePlacementStrategyAttribute : PlacementAttribute
    {
        public SamplePlacementStrategyAttribute() :
            base(new SamplePlacementStrategy())
        {
        }
    }
}
